[SUCTF 2019]EasySQL

总结

  • 用Bp抓包爆破查询过滤的关键字,找到合适的注入方法
  • 尝试用预编译绕过限制
  • 启用set sql_mode=pipes_as_concat模式,将||运算符用作字符串连接,即用作concat()函数同义词

题目

解题思路

输入1,出现回显:

尝试将 1 和 or 一起输入,即 1 or 1=1

出现回显:

这说明or被过滤了

这时我们要检查哪些关键字被过滤了,来判断注入方式

用Bp抓包再利用sql关键字字典对query进行爆破

发现过滤(部分):

1
flag|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|floor|extractvalue|updatexml|or|and|&|

盲注,联合注入,报错注入不可用!

尝试堆叠注入将多条SQL语句放在一起,并用分号;隔开

查数据库名

查表名

表Flag,可以确定flag在表Flag中

我们首先想到利用from来查询Flag,但是通过抓包分析可知,from关键字被过滤掉了,所以只能另寻他法

正常而言,我们使用预编译来绕过限制

1
1;sEt@a=concat("select * fr","om Flag");PRepare hello from @a;execute hello;#

但过滤了prepare,大小写绕过也不行

输入非零数字得到结果一直是1和而输入其余字符的数据就得不到回显=>来判断出内部的查询语句可能存在有||(即or:或运算)

默认情况下在MySQL中||运算符是逻辑或运算符(即or),但取决于PIPES_AS_CONCAT SQL模式

如果启用了set sql_mode=pipes_as_concat模式,则||运算符用作字符串连接,即用作concat()函数同义词

1
2
那么内置语句就可以猜测为:
sql="select post['query'] || flag from Flag";

查询语句:

1
1;set sql_mode=pipes_as_concat;select 1

得到flag

一点小补充:

select concat('f','lag') from Flag;

这种绕过flag的思路是不对的

因为这种会当做先select 'f','lag' from Flag 然后再使用concat将f和lag连接起来